package com.kiss.rpc.channelhandler.handler;

import com.kiss.rpc.compress.Compressor;
import com.kiss.rpc.compress.CompressorFactory;
import com.kiss.rpc.serialize.Serializer;
import com.kiss.rpc.serialize.SerializerFactory;
import com.kiss.rpc.transport.message.MessageFormatConstant;
import com.kiss.rpc.transport.message.RpcRequest;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import lombok.extern.slf4j.Slf4j;

/**
 * 自定义协议编码器
 * <p>
 * <pre>
 *   0    1    2    3    4    5    6    7    8    9    10   11   12   13   14   15   16   17   18   19   20   21   22
 *   +----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
 *   |    magic          |ver |head  len|    full length    | qt | ser|comp|              RequestId                |
 *   +-----+-----+-------+----+----+----+----+-----------+----- ---+--------+----+----+----+----+----+----+---+---+
 *   |                                                                                                             |
 *   |                                         body                                                                |
 *   |                                                                                                             |
 *   +--------------------------------------------------------------------------------------------------------+---+
 * </pre>
 * <p>
 * 4B magic(魔数)   --->myrpc.getBytes()
 * 1B version(版本)   ----> 1
 * 2B header length 首部的长度
 * 4B full length 报文总长度
 * 1B serialize
 * 1B compress
 * 1B requestType
 * 8B requestId
 * 8B timeStamp
 * <p>
 * body
 * <p>
 * 出站时，第一个经过的处理器
 *
 * @author it楠老师
 * @createTime 2023-07-02
 */

@Slf4j
public class RpcRequestEncoder extends MessageToByteEncoder<RpcRequest> {

    @Override
    protected void encode(ChannelHandlerContext channelHandlerContext, RpcRequest rpcRequest, ByteBuf byteBuf) throws Exception {
        byteBuf.writeBytes(MessageFormatConstant.MAGIC);
        byteBuf.writeByte(MessageFormatConstant.VERSION);
        byteBuf.writeShort(MessageFormatConstant.HEADER_LENGTH);
        byteBuf.writerIndex(byteBuf.writerIndex() + MessageFormatConstant.FULL_FIELD_LENGTH);

        byteBuf.writeByte(rpcRequest.getRequestType());
        byteBuf.writeByte(rpcRequest.getSerializeType());
        byteBuf.writeByte(rpcRequest.getCompressType());

        byteBuf.writeLong(rpcRequest.getRequestId());
        byteBuf.writeLong(rpcRequest.getTimeStamp());

        byte[] body = null;

        if (rpcRequest.getRequestPayload() != null) {
            Serializer serializer = SerializerFactory.getSerializer(rpcRequest.getSerializeType()).getImpl();
            body = serializer.serialize(rpcRequest.getRequestPayload());
            Compressor compressor = CompressorFactory.getCompressor(rpcRequest.getCompressType()).getImpl();
            body = compressor.compress(body);
        }

        CommonFuncs.writeFullLength(byteBuf, body);

        if (log.isDebugEnabled()) {
            log.debug("请求【{}】完成了客户端的请求编码", rpcRequest.getRequestId());
        }
    }
}
